package org.example.fboot.config;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.example.fboot.dto.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Data
@Slf4j
public class LoginUserDetails implements UserDetails {
    private final static Map<Long, Status> statusMap = new HashMap<>();
    private User user;

    public LoginUserDetails(User user) {
        this.user = user;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Collections.emptyList();
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

    /**
     * 是否没有过期
     *
     * @return
     */
    @Override
    public boolean isAccountNonExpired() {
        return !(Status.contain(Status.exp, user.getStatus()) && user.getExpDatetime().isBefore(LocalDateTime.now()));
    }

    /**
     * 是否没有被锁定
     *
     * @return
     */
    @Override
    public boolean isAccountNonLocked() {
        return Status.notContain(Status.lock, user.getStatus());
    }

    /**
     * 用户登录凭证是否没有过期
     *
     * @return
     */
    @Override
    public boolean isCredentialsNonExpired() {
        //获取到token判断
        return true;
    }

    /**
     * 登录用户是否生效
     *
     * @return
     */
    @Override
    public boolean isEnabled() {
        //同时不包含删除状态和失效状态
        return Status.notContain(Status.disable, user.getStatus()) && Status.notContain(Status.deleted, user.getStatus());
    }

    @AllArgsConstructor
    enum Status {
        /**
         * 锁定状态
         */
        lock(1),
        /**
         * 过期状态，
         */
        exp(1 << 1),
        /**
         * 失效状态
         */
        disable(1 << 2),
        /**
         * 删除状态
         */
        deleted(1 << 3),
        ;
        final long stat;

        /**
         * source状态中是否包含target状态
         *
         * @param target
         * @param source
         * @return
         */
        public static boolean contain(Status target, long source) {
            return (target.stat & source) != 0;
        }

        public static boolean notContain(Status target, long source) {
            return (target.stat & source) == 0;
        }

        /**
         * 将target状态添加到source中并返回
         *
         * @return
         */
        public static long addStatus(Status target, long source) {
            return target.stat | source;
        }

        /**
         * 将target状态从source中移除
         *
         * @return
         */
        public static long removeStatus(Status target, long source) {
            return (~target.stat) & source;
        }

    }

    public static void main(String[] args) throws InterruptedException {
        LocalDateTime dateTime = LocalDateTime.now();
        Thread.sleep(100);
        LocalDateTime now = LocalDateTime.now();
        System.out.println(dateTime.isBefore(now));
    }
}
